package com.haifeng.sbtx.api.exception;

import com.google.common.collect.Lists;
import com.haifeng.sbtx.common.base.BussinessException;
import com.haifeng.sbtx.common.base.ErrorCode;
import com.haifeng.sbtx.common.base.Rest;
import com.haifeng.sbtx.common.util.MessageUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;

/**
 * <p>
 *  全局异常捕获
 * </p>
 *
 * @author: Haifeng
 * @date: 2019-11-28
 */
@ControllerAdvice
public class GlobalExceptionAdvice {

    @Resource
    private MessageUtil messageUtil;

    /**
     * 处理异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public Rest globalException(Exception e){
        Rest restfulMessage=new Rest();
        restfulMessage.setSuccess(false);
        //参数校验未通过异常 @RequestBody参数校验失败
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
            List<ObjectError> errors = exception.getBindingResult().getAllErrors();
            StringBuffer sb = new StringBuffer();
            List<String> errorArr= Lists.newArrayList();
            for (ObjectError error : errors) {
                if (error instanceof FieldError){
                    FieldError fieldError=(FieldError)error;
                    errorArr.add(fieldError.getField()+fieldError.getDefaultMessage());
                }else{
                    errorArr.add(error.getObjectName()+error.getDefaultMessage());
                }
            }
            String errMsg=StringUtils.join(";",errorArr.toArray(new String[]{}));
            restfulMessage.setCode(ErrorCode.ERROR_JSON_NOT_VALID);
            restfulMessage.setMessage(errMsg);
        } else if (e instanceof ConstraintViolationException) {
            //@RequestParam 参数校验失败
            ConstraintViolationException exception = (ConstraintViolationException) e;
            StringBuffer sb = new StringBuffer();
            List<String> errorArr = Lists.newArrayList();
            for (ConstraintViolation constraint : exception.getConstraintViolations()) {
                errorArr.add(constraint.getInvalidValue() + "非法" + constraint.getMessage());
            }
            restfulMessage.setCode(ErrorCode.ERROR_PARAMS_NOT_VALID);
            restfulMessage.setMessage(StringUtils.join(";", errorArr.toArray(new String[]{})));
        }else if(e instanceof BussinessException){
            //手动抛出的业务异常
            BussinessException exception = (BussinessException)e;
            restfulMessage.setCode(exception.getErrCode());
            restfulMessage.setMessage(messageUtil.getMessage(exception.getErrCode()));
        }else{
            //其他异常
            restfulMessage.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            restfulMessage.setMessage(e.getMessage());
        }
        return restfulMessage;
    }
}
